package com.friend.chat.media.audio

import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.media.AudioFormat
import android.media.AudioRecord
import android.media.MediaRecorder
import android.media.audiofx.AcousticEchoCanceler
import android.util.Log
import androidx.core.app.ActivityCompat
import com.friend.chat.utils.Speex


/**
 * @des
 * @author batie fancy
 * @date 2022/12/18
 */
class AudioRecorder : Runnable {

    private var uid:String = ""
    private var toUid:String =""
    //表示数据来源 MediaRecorder.AudioSource.VOICE_COMMUNICATION
    private val audioSource: Int = MediaRecorder.AudioSource.VOICE_COMMUNICATION

    //表示采样率 一般设置为 44100
    private val sampleRateHz: Int = 8000

    //表示声道
    private val channelConfig: Int = AudioFormat.CHANNEL_IN_MONO

    //表示数据编码格式
    private val audioFormat: Int = AudioFormat.ENCODING_PCM_16BIT

    //音频录制对象
    private var audioRecord: AudioRecord? = null

    //回声消除
    private var canceler: AcousticEchoCanceler? = null

    //是否正在录制
    @Volatile
    private var isRecording = false

    companion object {

        var sInstance: AudioRecorder? = null

        @Synchronized
        fun getInstance(): AudioRecorder? {
            if (sInstance == null) {
                sInstance = AudioRecorder()
            }
            return sInstance
        }
    }


    public fun startRecord(context: Context,uid:String,toUid:String) {
        if (ActivityCompat.checkSelfPermission(
                context,
                Manifest.permission.RECORD_AUDIO
            ) != PackageManager.PERMISSION_GRANTED
        ) {
            return
        }
        this.uid = uid
        this.toUid = toUid
        //计算缓存大小
        var audioBufSize = AudioRecord.getMinBufferSize(sampleRateHz, channelConfig, audioFormat)

        if (null == audioRecord && audioBufSize != AudioRecord.ERROR_BAD_VALUE) {
            audioRecord =
                AudioRecord(audioSource, sampleRateHz, channelConfig, audioFormat, audioBufSize)
        }
        if (null == audioRecord){
            return
        }
       initAec(audioRecord!!.audioSessionId)
        Thread(this).start()
    }

    //消除回音
    private fun initAec(audioSession:Int):Boolean{
        if (null!=canceler){
            return false
        }
        if (!AcousticEchoCanceler.isAvailable()){
            return false
        }
        canceler = AcousticEchoCanceler.create(audioSession)
        canceler!!.enabled = true
        return canceler!!.enabled
    }


    override fun run() {
        if (audioRecord!!.state == AudioRecord.STATE_UNINITIALIZED) {
            return
        }
        // 在录音之前实例化一个编码类，在编码类中实现的数据的发送。
        // 在录音之前实例化一个编码类，在编码类中实现的数据的发送。
        val encoder: AudioEncoder = AudioEncoder.getInstance()
        encoder.startEncoding(uid, toUid)
        audioRecord!!.startRecording()

        this.isRecording = true
        Log.e("ccc", "开始编码")
        val size: Int = Speex.getInstance().getFrameSize()

        val samples = ShortArray(size)

        while (isRecording) {
            try {
                val bufferRead = audioRecord!!.read(samples, 0, size)
                if (bufferRead > 0) {
                    encoder.addData(samples, bufferRead)
                }
            } catch (e: Exception) {
            }
        }
        encoder.stopEncoding()
    }

    // 关闭录制
    fun stopRecording() {
        isRecording = false
        sInstance = null
    }

    // 是否正在录制、
    fun isRecording(): Boolean {
        return isRecording
    }
}